
#ifndef __EV_PACKET_H__
#define __EV_PACKET_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>

/* ev packet tail length */
/*
 * data[n]  (n bytes)
 * sof      (1 byte)
 * user     (1 byte)
 * seq      (1 byte)
 * cmd      (2 bytes)
 * length   (2 bytes)
 * chksum   (1 byte)
 * crc16    (2 bytes)
 */
#define EV_PACKET_TAIL_LEN      10
#define EV_PACKET_MAX_LEN       128
#define EV_PACKET_MAX_DATA_LEN  (EV_PACKET_MAX_LEN - EV_PACKET_TAIL_LEN)

#define EV_PACKET_MAGIC         0xC96D
#define EV_PACKET_SOF           0xA5

/* ev packet */
typedef struct {
    uint8_t user;   // if user == 0, it's a native packet, else it's a router packet
    uint8_t seq;
    uint16_t cmd;
    uint32_t len;
    uint8_t data[EV_PACKET_MAX_DATA_LEN];
} ev_packet_t;

/* ev parser */
struct ev_parser;
typedef struct ev_parser ev_parser_t;
struct ev_parser {
    void *arg;
    void (*cb)(const ev_parser_t *parser, const ev_packet_t *packet);
    uint16_t crc;
    uint32_t offset;
    uint8_t buf[EV_PACKET_MAX_LEN];
};

int ev_parser_init(ev_parser_t *parser,
                   void *arg,
                   void (*cb)(const ev_parser_t *, const ev_packet_t *)
);
int ev_parser_reset(ev_parser_t *parser);
int ev_parser_feed_one(ev_parser_t *parser, uint8_t data);
int ev_parser_feed(ev_parser_t *parser, const uint8_t *data, uint32_t len);

int ev_packet_make(const ev_packet_t *pkt, uint8_t *data, uint32_t *len);
int ev_packet_check(const uint8_t *data, uint32_t len, ev_packet_t *pkt);

#ifdef __cplusplus
}
#endif


#endif /* __EV_PACKET_H__ */
